<?php

namespace app\admin\controller\user;

use Throwable;
use ba\Random;
use app\common\controller\Backend;
use app\admin\model\User as UserModel;
use think\facade\Db;
use think\db\exception\PDOException;
use think\exception\ValidateException;

use ba\Exception;

class User extends Backend
{
    /**
     * @var object
     * @phpstan-var UserModel
     */
    protected object $model;


    protected array $withJoinTable = [];

    protected string|array $quickSearchField = ['username', 'nickname'];


    public function initialize(): void
    {

        parent::initialize();
        $this->model = new UserModel();
    }

    /**
     * 获取用户信息
     */
    public function getUserInfo():void{
        $user_id = $this->request->get('user_id');
        $result = $this->model->find($user_id);
        $this->success('', $result);
    }

    /**
     * 添加补价
     */
    public function premium(): void{
        $param = $this->request->param();
//        print_r($param);die;
        if(empty($param['date'])) $this->error('日期不能为空');
        if(empty($param['money'])) $this->error('金额不能为空');
        if($param['money'] <= 0) $this->error('金额不能为负数');

        db::startTrans();
        try {
            $insert = [
                'user_id' => $param['user_id'],
                'money' => $param['money'],
                'create_time' => strtotime($param['date'])
            ];
            db::name('premium')->insert($insert);
            db::name('user')->where(['id' => $param['user_id']])->setDec('money', $param['money']);
            $user = db::name('user')->where(['id' => $param['user_id']])->find();
            $money_log_insert = [
                'user_id' => $param['user_id'],
                'money' => $param['money'],
                'before' => $user['money'],
                'after' => $user['money'] - $param['money'],
                'memo' => '补价',
                'create_time' => $this->timestamp
            ];
            db::name('user_money_log')->insert($money_log_insert);


            db::commit();
        }catch (\Exception $e){
            db::rollback();
            $this->error($e->getMessage());
        }
        $this->success();
    }

    /**
     * 添加运费
     */
    public function carriage(): void{
        $param = $this->request->param();
        if(empty($param['date'])) $this->error('日期不能为空');
        if(empty($param['money'])) $this->error('金额不能为空');
        if($param['money'] <= 0) $this->error('金额不能为负数');

        db::startTrans();
        try {
            $insert = [
                'user_id' => $param['user_id'],
                'money' => $param['money'],
                'create_time' => strtotime($param['date'])
            ];
            db::name('carriage')->insert($insert);
            db::name('user')->where(['id' => $param['user_id']])->setDec('money', $param['money']);
            $user = db::name('user')->where(['id' => $param['user_id']])->find();
            $money_log_insert = [
                'user_id' => $param['user_id'],
                'money' => $param['money'],
                'before' => $user['money'],
                'after' => $user['money'] - $param['money'],
                'memo' => '运费',
                'create_time' => $this->timestamp
            ];
            db::name('user_money_log')->insert($money_log_insert);


            db::commit();
        }catch (\Exception $e){
            db::rollback();
            $this->error($e->getMessage());
        }
        $this->success();
    }

    /**
     * 设置用户的品牌利润
     */
    public function profit(): void{
        $param = $this->request->param('info');
//        print_r($param);die;

        foreach($param['brandAll'] as $val){
            if(!empty($val['value'])){
                if($val['value'] < 0) $this->error('利润不能为负数');
            }
        }

        db::startTrans();
        try {
            foreach($param['brandAll'] as $val){
                $where = [
                    'user_id' => $param['id'],
                    'brand_id' => $val['id'],
                ];
                $user_brand_profit = Db::name('user_brand_profit')->where($where)->find();
                if($user_brand_profit){
                    if(empty($val['value'])){
                        db::name('user_brand_profit')->where(['id' => $user_brand_profit['id']])->delete();
                    }else{
                        db::name('user_brand_profit')->where(['id' => $user_brand_profit['id']])->update(['profit' => $val['value'], 'update_time' => $this->timestamp]);
                    }
                }else{
                    if(!empty($val['value'])){
                        $insert = [
                            'user_id' => $param['id'],
                            'brand_id' => $val['id'],
                            'profit' => $val['value'],
                            'create_time' => $this->timestamp
                        ];
                        db::name('user_brand_profit')->insert($insert);
                    }
                }
            }
            db::commit();
        }catch (\Exception $e){
            db::rollback();
            $this->error($e->getMessage());
        }
        $this->success();
    }

    /**
     * 设置代购费
     */
    public function agencyFee($id = null):void {
        $data = $this->request->post();
        $row = $this->model->find($id);
        if (!$row) {
            $this->error(__('Record not found'));
        }

        if ($this->request->isPost()) {
            if(empty($data['agency_fee']) || $data['agency_fee'] < 0){
                $agency_fee = 0;
            }elseif($data['agency_fee'] > 100){
                $agency_fee = 100;
            }else{
                $agency_fee = $data['agency_fee'];
            }
            $agency_fee = (int) $agency_fee;
            $update = [
                'agency_fee' => $agency_fee,
                'update_time' => $this->timestamp
            ];

            $result = Db::name('admin')->where(['id' => $data['id']])->update($update);
            if($result){
                $this->success('', [
                    'agency_fee' => $agency_fee
                ]);
            }else{
                $this->error();
            }
        }

    }

    /**
     * 查看
     * @throws Throwable
     */

    public function index(): void
    {

        $this->request->filter(['strip_tags', 'trim']);
        if ($this->request->param('select')) {
            $this->select();
        }

        list($where, $alias, $limit, $order) = $this->queryBuilder();

        $res = $this->model
            ->withoutField('password,salt')
            ->with(['userData'])
            ->alias($alias)
            ->where($where)
            ->where(['outstation_id' => $this->outstation_id])
            ->order($order)
            ->paginate($limit);

        $list = $res->items();

        $this->success('', [
            'list' => $list,
            'total' => $res->total(),
            'remark' => get_route_remark(),
        ]);
    }

    /**
     * 添加
     * @throws Throwable
     */
    public function add(): void {
        if ($this->request->isPost()) {
            $data = $this->request->post();
            if (!$data) {
                $this->error(__('Do not submit empty data'));
            }
            $data = $this->excludeFields($data);
            $username = empty($data['username']) ? '' : trim($data['username']);
            $email = $data['email'] ?? '';
            if (empty($username)) $this->error(__('%s can not be empty', [__('username')]));
            if (empty($data['password'])) $this->error(__('%s can not be empty', [__('password')]));
            $salt = Random::build('alnum', 16);
            $passwd = encrypt_password($data['password'], $salt);
            $where = [
                ['username', '=', $username],
                ['outstation_id', '=', $this->outstation_id]
            ];
            $user = db::name('user')->where($where)->find();
            if ($user) $this->error(__('Account already exists'));
            if (!empty($email)) {
                $where = [
                    ['email', '=', $email],
                    ['outstation_id', '=', $this->outstation_id]
                ];
                $user = db::name('admin')->where($where)->find();
                if($user) $this->error(__('Email already exists'));
            }
            $result = false;
//            print_r($data);die;
            $this->model->startTrans();
            try {
                // 模型验证
                if ($this->modelValidate) {
                    $validate = str_replace("\\model\\", "\\validate\\", get_class($this->model));
                    if (class_exists($validate)) {
                        $validate = new $validate;
                        if ($this->modelSceneValidate) $validate->scene('add');
                        $validate->check($data);
                    }
                }
                $userInsert = [
                    'username' => $username,
                    'email' => $email,
                    'password' => $passwd,
                    'salt' => $salt,
                    'big' => empty($data['big']) ? 0 : $data['big'],
                    'small' => empty($data['small']) ? 0 : $data['small'],
                    'contact' => $data['contact'] ?? '',
                    'wechat' => $data['wechat'] ?? '',
                    'contact_designated_logistics' => $data['contact_designated_logistics'] ?? '',
                    'designated_logistics' => $data['designated_logistics'] ?? '',
                    'note' => $data['note'] ?? '',
                    'create_time' => $this->timestamp,
                    'outstation_id' => $this->outstation_id
                ];
                $user_id = Db::name('user')->insertGetId($userInsert);
                $user_data_insert = [
                    'user_id' => $user_id,
                    'company_name' => empty($data['userData']['company_name']) ? null : $data['userData']['company_name'],
                ];
                $result = Db::name('user_data')->insert($user_data_insert);
                Db::commit();
            } catch (ValidateException|Exception|PDOException $e) {
                Db::rollback();
                $this->error($e->getMessage());
            }
            if ($result !== false) {
                $this->success(__('Added successfully'));
            } else {
                $this->error(__('No rows were added'));
            }
        }
        $this->error(__('Parameter error'));
    }

    /**
     * 编辑
     * @param string|int|null $id
     * @throws Throwable
     */
    public function edit(string|int $id = null): void {
        $row = $this->model->with(['userData'])->find($id);
        if (!$row) {
            $this->error(__('Record not found'));
        }
        if ($this->request->isPost()) {
            $data = $this->request->post();
            if (!$data) {
                $this->error(__('Parameter %s can not be empty', ['']));
            }
            $data   = $this->excludeFields($data);
//            print_r($data);die;
            $password = $this->request->post('password', '');
            if ($password) {
                $this->model->resetPassword($id, $password);
            }
            if(isset($data['password'])) unset($data['password']);
            $email = empty($data['email']) ? '' : trim($data['email']);
            if (!empty($email)) {
                $where = [
                    ['email', '=', $email],
                    ['id', '<>', $row['id']],
                    ['outstation_id', '=', $this->outstation_id]
                ];
                if (db::name('admin')->where($where)->find()) $this->error(__('Email already exists'));
            }
            $result = false;
//            print_r($data);die;
            $this->model->startTrans();
            try {
                // 模型验证
                if ($this->modelValidate) {
                    $validate = str_replace("\\model\\", "\\validate\\", get_class($this->model));
                    if (class_exists($validate)) {
                        $validate = new $validate;
                        if ($this->modelSceneValidate) $validate->scene('edit');
                        $validate->check($data);
                    }
                }
                $userDataUpdate = [
                    'company_name' => $data['userData']['company_name'],
                    'update_time' => $this->timestamp
                ];
                Db::name('user_data')->where(['user_id' => $id])->update($userDataUpdate);
                $result = $row->save($data);
                $this->model->commit();
            } catch (Throwable $e) {
                $this->model->rollback();
                $this->error($e->getMessage());
            }
            if ($result !== false) {
                $this->success(__('Update successful'));
            } else {
                $this->error(__('No rows updated'));
            }

            parent::edit();
        }

        unset($row->salt);
        $row->password = '';
        $this->success('', [
            'row' => $row
        ]);
    }

    /**
     * 重写select
     * @throws Throwable
     */
    public function select(): void
    {

        $this->request->filter(['strip_tags', 'trim']);

        list($where, $alias, $limit, $order) = $this->queryBuilder();
        $res = $this->model
            ->withJoin($this->withJoinTable, $this->withJoinType)
            ->alias($alias)
            ->where($where)
            ->where(['outstation_id' => $this->outstation_id])
            ->order($order)
            ->paginate($limit);

        foreach ($res as $re) {
            $re->nickname_text = $re->username . '(ID:' . $re->id . ')';
        }

        $this->success('', [
            'list' => $res->items(),
            'total' => $res->total(),
            'remark' => get_route_remark(),
        ]);
    }
}